#ifndef _SYS_ENV_H_
#define _SYS_ENV_H_

#include "FanObj.h"
#include "SysTypes.h"

#define ENV_VTABLE(self)   ((EnvVTable*)((FanObj*)self)->vtable)


extern Type*    Env_classType;
extern VTable*  Env_classVTable;


/* [sys::Env] Attributes */
struct Env
{
  FanObj        super;
};


/* [sys::Env] Virtual-table */
typedef struct EnvVTable
{
  FanObjVTable  super;
  void          (*addShutdownHook)(Env* self, Func* hook);
  List*         (*args)(Env* self);
  Type*         (*compileScript_1)(Env* self, File* f);
  Type*         (*compileScript)(Env* self, File* f, Map* options);
  Str*          (*config_2)(Env* self, Pod* pod, Str* key);
  Str*          (*config)(Env* self, Pod* pod, Str* key, Str* def);
  Map*          (*diagnostics)(Env* self);
  OutStream*    (*err)(Env* self);
  void          (*exit_0)(Env* self);
  void          (*exit)(Env* self, Int status);
  List*         (*findAllFiles)(Env* self, Uri* uri);
  List*         (*findAllPodNames)(Env* self);
  File*         (*findFile_1)(Env* self, Uri* uri);
  File*         (*findFile)(Env* self, Uri* uri, Bool checked);
  File*         (*findPodFile)(Env* self, Str* podName);
  void          (*gc)(Env* self);
  File*         (*homeDir)(Env* self);
  Str*          (*host)(Env* self);
  InStream*     (*in)(Env* self);
  List*         (*index)(Env* self, Str* key);
  Str*          (*locale_2)(Env* self, Pod* pod, Str* key);
  Str*          (*locale_3)(Env* self, Pod* pod, Str* key, Str* def);
  Str*          (*locale)(Env* self, Pod* pod, Str* key, Str* def, Locale* locale);
  OutStream*    (*out)(Env* self);
  Map*          (*props)(Env* self, Pod* pod, Uri* uri, Duration* maxAge);
  Bool          (*removeShutdownHook)(Env* self, Func* hook);
  File*         (*tempDir)(Env* self);
  Str*          (*user)(Env* self);
  Map*          (*vars)(Env* self);
  File*         (*workDir)(Env* self);
} EnvVTable;


/* [sys::Env] Methods and fields */
void            Env_make_0(Env* self);
void            Env_make(Env* self, Env* parent);
Env*            Env_cur(void);
Env*            Env_parent(Env* self);
Str*            Env_platform(Env* self);
Str*            Env_os(Env* self);
Str*            Env_arch(Env* self);
Str*            Env_runtime(Env* self);
Int             Env_idHash(Env* self, NullableObj obj);
List*           Env_args(Env* self);
Map*            Env_vars(Env* self);
Map*            Env_diagnostics(Env* self);
void            Env_gc(Env* self);
Str*            Env_host(Env* self);
Str*            Env_user(Env* self);
InStream*       Env_in(Env* self);
OutStream*      Env_out(Env* self);
OutStream*      Env_err(Env* self);
File*           Env_homeDir(Env* self);
File*           Env_workDir(Env* self);
File*           Env_tempDir(Env* self);
File*           Env_findFile_1(Env* self, Uri* uri);
File*           Env_findFile(Env* self, Uri* uri, Bool checked);
List*           Env_findAllFiles(Env* self, Uri* uri);
File*           Env_findPodFile(Env* self, Str* podName);
List*           Env_findAllPodNames(Env* self);
Type*           Env_compileScript_1(Env* self, File* f);
Type*           Env_compileScript(Env* self, File* f, Map* options);
List*           Env_index(Env* self, Str* key);
Map*            Env_props(Env* self, Pod* pod, Uri* uri, Duration* maxAge);
Str*            Env_config_2(Env* self, Pod* pod, Str* key);
Str*            Env_config(Env* self, Pod* pod, Str* key, Str* def);
Str*            Env_locale_2(Env* self, Pod* pod, Str* key);
Str*            Env_locale_3(Env* self, Pod* pod, Str* key, Str* def);
Str*            Env_locale(Env* self, Pod* pod, Str* key, Str* def, Locale* locale);
void            Env_exit_0(Env* self);
void            Env_exit(Env* self, Int status);
void            Env_addShutdownHook(Env* self, Func* hook);
Bool            Env_removeShutdownHook(Env* self, Func* hook);


/* [sys::Env] Type-system functions */
Type*           Env_initType(void);
VTable*         Env_initVTable(void);
void            Env_initStatic(void);


#endif
